
<template>
    <div class="threeJsPrc62">
      <div class="myCanvas" ref="myCanvas"></div>
    </div>
</template>

<script lang="ts">
import { Vue, Options } from 'vue-property-decorator';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
const scene = new THREE.Scene();
scene.add(new THREE.AxesHelper(250));
const camera = new THREE.PerspectiveCamera();
camera.fov = 70;
camera.near = 1;
camera.near = 10000;
const renderer = new THREE.WebGLRenderer({
  alpha: true,
});
renderer.debug.checkShaderErrors = false;
renderer.setClearColor(0xb9d3ff, 1);

@Options({ components: {
} })
export default class ThreeJsPrc62 extends Vue {
  public rect: DOMRect|null=null;
  public dpr =750 / window.innerWidth;
  public controls!: OrbitControls;

  public sphereMesh(R: number, x: number, y: number, z: number) {
    const geometry = new THREE.SphereGeometry(R, 25, 25); // 球体几何体
    const material = new THREE.MeshPhongMaterial({
      color: 0x0000ff,
    }); // 材质对象Material
    const mesh = new THREE.Mesh(geometry, material); // 创建网格模型对象
    mesh.position.set(x, y, z);
    return mesh;
  }
  public cylinderMesh(R: number, h: number, x: number, y: number, z: number) {
    const geometry = new THREE.CylinderGeometry(R, R, h, 25, 25); // 球体几何体
    const material = new THREE.MeshPhongMaterial({
      color: 0x0000ff,
    }); // 材质对象Material
    const mesh = new THREE.Mesh(geometry, material); // 创建网格模型对象
    mesh.position.set(x, y, z);
    return mesh;
  }

  public mounted() {
    this.rect = (this.$el as HTMLElement).getBoundingClientRect();
    (this.$refs.myCanvas as HTMLDivElement).append(renderer.domElement);
    renderer.setPixelRatio(this.dpr);
    renderer.setSize(this.rect.width, this.rect.height, false);
    camera.aspect = this.rect.width / this.rect.height;
    camera.position.set(200, 100, 200);
    camera.lookAt(scene.position);
    renderer.render(scene, camera);

    // 头部网格模型和组
    const headMesh = this.sphereMesh(10, 0, 0, 0);
    headMesh.name = '脑壳';
    const leftEyeMesh = this.sphereMesh(1, 8, 5, 4);
    leftEyeMesh.name = '左眼';
    const rightEyeMesh = this.sphereMesh(1, 8, 5, -4);
    rightEyeMesh.name = '右眼';
    const headGroup = new THREE.Group();
    headGroup.name = '头部';
    headGroup.add(headMesh, leftEyeMesh, rightEyeMesh);
    // 身体网格模型和组
    const neckMesh = this.cylinderMesh(3, 10, 0, -15, 0);
    neckMesh.name = '脖子';
    const bodyMesh = this.cylinderMesh(14, 30, 0, -35, 0);
    bodyMesh.name = '腹部';
    const leftLegMesh = this.cylinderMesh(4, 60, 0, -80, -7);
    leftLegMesh.name = '左腿';
    const rightLegMesh = this.cylinderMesh(4, 60, 0, -80, 7);
    rightLegMesh.name = '右腿';
    const legGroup = new THREE.Group();
    legGroup.name = '腿';
    legGroup.add(leftLegMesh, rightLegMesh);
    const bodyGroup = new THREE.Group();
    bodyGroup.name = '身体';
    bodyGroup.add(neckMesh, bodyMesh, legGroup);
    // 人Group
    const personGroup = new THREE.Group();
    personGroup.name = '人';
    personGroup.add(headGroup, bodyGroup);
    personGroup.translateY(50);
    scene.add(personGroup);

    scene.traverse((obj) => {
      if (obj.type === 'Group') {
        console.log(obj.name);
      }
      if (obj.type === 'Mesh') {
        // console.log(obj);
        console.log(`  ${obj.name}`);
        // obj.material.color.set(0xffff00);
      }
      if (obj.name === '左眼' || obj.name === '右眼') {
        // obj.material.color.set(0x000000);
      }
      console.log(obj.id);
    });

    renderer.setAnimationLoop(() => {
      renderer.render(scene, camera);
    });

    this.controls = new OrbitControls(camera, renderer.domElement);
  }
}
</script>

<style lang="postcss" scoped>
.threeJsPrc62{
  touch-action: none;
  width: 100%;
  height: 100%;
  background: grey;
}
</style>
